﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using GalaSoft.MvvmLight;
using Microsoft.Practices.ServiceLocation;

using WK35705XML;
using UMPInput = WK35705XML.UMPInput;
using UMPOutput = WK35705XML.UMPOutput;

namespace UIExample.ViewModel
{
    public class IOParameterViewModel : ViewModelBase

    {
        public decimal _value;
        private IUMPIO _io;
        private UMPViewModel _parentViewModel;

        private static List<IOParameterViewModel> parameters = new List<IOParameterViewModel>();

        public IOParameterViewModel()
        {
            parameters.Add(this);
        }

        ~IOParameterViewModel()
        {
            parameters.Remove(this);
        }

        public static void ResetVisited()
        {
            foreach (var par in parameters)
            {
                par.BlockChangingOther = false;
            }
        }
        public IOParameterViewModel(WK35705XML.UMPInput umpInput, UMPViewModel umpViewModel):this()
           
        {
            IO = umpInput;
            ParentViewModel = umpViewModel;
        }

        public IOParameterViewModel(WK35705XML.UMPOutput umpOutput, UMPViewModel umpViewModel)
            : this()
        {
            
            IO = umpOutput;
            ParentViewModel = umpViewModel;
        }

        public UMPViewModel ParentViewModel
        {
            get { return _parentViewModel; }
            set
            {
                if (Equals(value, _parentViewModel)) return;
                _parentViewModel = value;
                RaisePropertyChanged("ParentViewModel");
                RaisePropertyChanged("Independent");
            }
        }

        public void Refresh()
        {
            RaisePropertyChanged("Independent");
        }

        public string ShowName => IO.name + " (" + IO.unit + ")";

        public bool Independent
        {
            get
            {
                if (ParentViewModel == null || IO == null || string.IsNullOrWhiteSpace(ParentViewModel.Equations))
                    return false;
                bool dependent = false;
                try
                {
                    foreach (var equation in ParentViewModel.Equations.Split(';'))
                    {
                        var indep = equation.Split('=');
                        if (indep[0].Trim() == IO.name)
                            dependent = true;
                    }
                }
                catch
                {
                    dependent = false;
                }
                return !dependent;
            }
        }

  
       

        public WK35705XML.IUMPIO IO

        {
            get { return _io; }
            set
            {
                if (Equals(value, _io)) return;
                _io = value;
                RaisePropertyChanged("IO");
                RaisePropertyChanged("Independent");
            }
        }

        public Decimal Value
        {
            get { return _value; }
            set
            {
                
                if (value == _value) 
                    return;
                _value = value;


                RaisePropertyChanged("Value");
                RaisePropertyChanged("DependentValue");
                if(Independent)
                    ParentViewModel.Calculate();
            }
        }

        public Decimal DependentValue
        {
            get { return _value; }
            set
            {
                UMPLink.ResetVisited();
                ResetVisited();
                if (value == _value)
                    return;
                _value = value;


                RaisePropertyChanged("Value");
                RaisePropertyChanged("DependentValue");
                ParentViewModel.Calculate();
            }
        }

        public bool BlockChangingOther { get; set; }


        public void UpdateValue()
        {
            List<UMPLink> links = ParentViewModel.GetLinks(this);
            if(links.Count == 0)
                return;
            decimal v = 0;
            foreach (var umpLink in links)
            {
                v += umpLink.Value;
            }
            BlockChangingOther = true;
            Value = v;
            
        }
    }
    
}
